home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 14
/
CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso
/
CUCD
/
Programming
/
RKMLibsPrgs
/
intuition
/
gadgets
/
strhooks.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-03
|
12KB
|
349 lines
;/* strhooks.c - Execute me to compile me with SAS C 5.10
LC -b1 -cfistq -v -y -j73 strhooks.c
Blink FROM LIB:c.o,strhooks.o TO strhooks LIBRARY LIB:LC.lib,LIB:Amiga.lib
quit
*/
/*
Copyright (c) 1992 Commodore-Amiga, Inc.
This example is provided in electronic form by Commodore-Amiga, Inc. for
use with the "Amiga ROM Kernel Reference Manual: Libraries", 3rd Edition,
published by Addison-Wesley (ISBN 0-201-56774-1).
The "Amiga ROM Kernel Reference Manual: Libraries" contains additional
information on the correct usage of the techniques and operating system
functions presented in these examples. The source and executable code
of these examples may only be distributed in free electronic form, via
bulletin board or as part of a fully non-commercial and freely
redistributable diskette. Both the source and executable code (including
comments) must be included, without modification, in any copy. This
example may not be published in printed form or distributed with any
commercial product. However, the programming techniques and support
routines set forth in these examples may be used in the development
of original executable software products for Commodore Amiga computers.
All other rights reserved.
This example is provided "as-is" and is subject to change; no
warranties are made. All use is at your own risk. No liability or
responsibility is assumed.
*/
/*
** strhooks.c - string gadget hooks demo
**
** WARNING: This file contains "callback" functions.
** You must disable stack checking (SAS -v flag) for them to work.
*/
#define INTUI_V36_NAMES_ONLY
#include <exec/types.h>
#include <exec/memory.h>
#include <utility/hooks.h>
#include <devices/inputevent.h>
#include <intuition/intuition.h>
#include <intuition/sghooks.h>
#include <graphics/displayinfo.h>
#include <clib/intuition_protos.h>
#include <clib/utility_protos.h>
#include <clib/exec_protos.h>
#ifdef LATTICE
int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */
int chkabort(void) { return(0); } /* really */
#endif
/* our function prototypes */
BOOL IsHexDigit(UBYTE test_char);
ULONG str_hookRoutine(struct Hook *hook, struct SGWork *sgw, ULONG *msg);
void initHook(struct Hook *hook, ULONG (*ccode)());
VOID handleWindow(struct Vars *vars);
struct Library *IntuitionBase;
struct Library *UtilityBase;
#define SG_STRLEN (44)
#define MYSTRGADWIDTH (200)
#define INIT_LATER 0
/* A border for the string gadget */
UWORD strBorderData[] = /* init elements 5 and 7 later (height adjust) */
{
0,0, MYSTRGADWIDTH + 3,0, MYSTRGADWIDTH + 3,INIT_LATER,
0,INIT_LATER, 0,0,
};
struct Border strBorder =
{
-2,-2, 1, 0,JAM1,5,strBorderData,NULL,
};
/* We'll dynamically allocate/clear most structures, buffers */
struct Vars
{
struct Window *sgg_Window;
struct Gadget sgg_Gadget;
struct StringInfo sgg_StrInfo;
struct StringExtend sgg_Extend;
struct Hook sgg_Hook;
UBYTE sgg_Buff[SG_STRLEN];
UBYTE sgg_WBuff[SG_STRLEN];
UBYTE sgg_UBuff[SG_STRLEN];
};
/* Main entry point.
**
** Open all required libraries, set-up the string gadget.
** Prepare the hook, open the sgg_Window and go...
*/
VOID main(int argc, char **argv)
{
struct Vars *vars;
struct Screen *screen;
struct DrawInfo *drawinfo;
if (IntuitionBase = OpenLibrary("intuition.library", 37L))
{
if (UtilityBase = OpenLibrary("utility.library", 37L))
{
/* get the correct pens for the screen. */
if (screen = LockPubScreen(NULL))
{
if (drawinfo = GetScreenDrawInfo(screen))
{
vars = (struct Vars *)AllocMem(sizeof(struct Vars),MEMF_CLEAR);
if (vars != NULL)
{
vars->sgg_Extend.Pens[0] = drawinfo->dri_Pens[FILLTEXTPEN];
vars->sgg_Extend.Pens[1] = drawinfo->dri_Pens[FILLPEN];
vars->sgg_Extend.ActivePens[0] = drawinfo->dri_Pens[FILLTEXTPEN];
vars->sgg_Extend.ActivePens[1] = drawinfo->dri_Pens[FILLPEN];
vars->sgg_Extend.EditHook = &(vars->sgg_Hook);
vars->sgg_Extend.WorkBuffer = vars->sgg_WBuff;
vars->sgg_StrInfo.Buffer = vars->sgg_Buff;
vars->sgg_StrInfo.UndoBuffer = vars->sgg_UBuff;
vars->sgg_StrInfo.MaxChars = SG_STRLEN;
vars->sgg_StrInfo.Extension = &(vars->sgg_Extend);
/* There should probably be a border around the string gadget.
** As is, it is hard to locate when disabled.
*/
vars->sgg_Gadget.LeftEdge = 20;
vars->sgg_Gadget.TopEdge = 30;
vars->sgg_Gadget.Width = MYSTRGADWIDTH;
vars->sgg_Gadget.Height = screen->RastPort.TxHeight;
vars->sgg_Gadget.Flags = GFLG_GADGHCOMP | GFLG_STRINGEXTEND;
vars->sgg_Gadget.Activation = GACT_RELVERIFY;
vars->sgg_Gadget.GadgetType = GTYP_STRGADGET;
vars->sgg_Gadget.SpecialInfo = &(vars->sgg_StrInfo);
vars->sgg_Gadget.GadgetRender = (APTR)&strBorder;
strBorderData[5] = strBorderData[7] =
screen->RastPort.TxHeight + 3;
initHook(&(vars->sgg_Hook), str_hookRoutine);
if (vars->sgg_Window = OpenWindowTags(NULL,
WA_PubScreen, screen,
WA_Left, 21, WA_Top, 20,
WA_Width, 500, WA_Height, 150,
WA_MinWidth, 50, WA_MaxWidth, ~0,
WA_MinHeight, 30, WA_MaxHeight, ~0,
WA_SimpleRefresh, TRUE,
WA_NoCareRefresh, TRUE,
WA_RMBTrap, TRUE,
WA_IDCMP, IDCMP_GADGETUP | IDCMP_CLOSEWINDOW,
WA_Flags, WFLG_CLOSEGADGET | WFLG_NOCAREREFRESH |
WFLG_DRAGBAR | WFLG_DEPTHGADGET |
WFLG_SIMPLE_REFRESH,
WA_Title, "String Hook Accepts HEX Digits Only",
WA_Gadgets, &(vars->sgg_Gadget),
TAG_DONE))
{
handleWindow(vars);
CloseWindow(vars->sgg_Window);
}
FreeMem(vars,sizeof(struct Vars));
}
FreeScreenDrawInfo(screen, drawinfo);
}
UnlockPubScreen(NULL, screen);
}
CloseLibrary(UtilityBase);
}
CloseLibrary(IntuitionBase);
}
}
/*
** This is an example string editing hook, which shows the basics of
** creating a string editing function. This hook restricts entry to
** hexadecimal digits (0-9, A-F, a-f) and converts them to upper case.
** To demonstrate processing of mouse-clicks, this hook also detects
** clicking on a character, and converts it to a zero.
**
** NOTE: String editing hooks are called on Intuition's task context,
** so the hook may not use DOS and may not cause Wait() to be called.
*/
ULONG str_hookRoutine(struct Hook *hook, struct SGWork *sgw, ULONG *msg)
{
UBYTE *work_ptr;
ULONG return_code;
/* Hook must return non-zero if command is supported.
** This will be changed to zero if the command is unsupported.
*/
return_code = ~0L;
if (*msg == SGH_KEY)
{
/* key hit -- could be any key (Shift, repeat, character, etc.) */
/* allow only upper case characters to be entered.
** act only on modes that add or update characters in the buffer.
*/
if ((sgw->EditOp == EO_REPLACECHAR) ||
(sgw->EditOp == EO_INSERTCHAR))
{
/* Code contains the ASCII representation of the character
** entered, if it maps to a single byte. We could also look
** into the work buffer to find the new character.
**
** sgw->Code == sgw->WorkBuffer[sgw->BufferPos - 1]
**
** If the character is not a legal hex digit, don't use
** the work buffer and beep the screen.
*/
if (!IsHexDigit(sgw->Code))
{
sgw->Actions |= SGA_BEEP;
sgw->Actions &= ~SGA_USE;
}
else
{
/* And make it upper-case, for nicety */
sgw->WorkBuffer[sgw->BufferPos - 1] = ToUpper(sgw->Code);
}
}
}
else if (*msg == SGH_CLICK)
{
/* mouse click
** zero the digit clicked on
*/
if (sgw->BufferPos < sgw->NumChars)
{
work_ptr = sgw->WorkBuffer + sgw->BufferPos;
*work_ptr = '0';
}
}
else
{
/* UNKNOWN COMMAND
** hook should return zero if the command is not supported.
*/
return_code = 0;
}
return(return_code);
}
/*
** This is a function which converts register-parameter
** hook calling convention into standard C conventions.
** It only works with SAS C 5.0+
**
** Without the fancy __asm stuff, you'd probably need to
** write this in assembler.
**
** You could conceivably declare all your C hook functions
** this way, and eliminate the middleman (you'd initialize
** the h_Entry field to your C function's address, and not
** bother with the h_SubEntry field).
**
** This is nice and easy, though, and since we're using the
** small data model, using a single interface routine like this
** (which does the necessary __saveds), it might
** actually turn out to be smaller to use a single entry point
** like this rather than declaring each of many hooks __saveds.
*/
ULONG __saveds __asm hookEntry(register __a0 struct Hook *hookptr,
register __a2 void *object,
register __a1 void *message)
{
return((*hookptr->h_SubEntry)(hookptr, object, message));
}
/*
** Initialize the hook to use the hookEntry() routine above.
*/
void initHook(struct Hook *hook, ULONG (*ccode)())
{
hook->h_Entry = hookEntry;
hook->h_SubEntry = ccode;
hook->h_Data = 0; /* this program does not use this */
}
/*
** Process messages received by the sgg_Window. Quit when the close gadget
** is selected.
*/
VOID handleWindow(struct Vars *vars)
{
struct IntuiMessage *msg;
ULONG class;
USHORT code;
for (;;)
{
Wait(1L << vars->sgg_Window->UserPort->mp_SigBit);
while (msg =
(struct IntuiMessage *)GetMsg(vars->sgg_Window->UserPort))
{
/* Stash message contents and reply, important when message
** triggers some lengthy processing
*/
class = msg->Class;
code = msg->Code;
ReplyMsg((struct Message *)msg);
switch (class)
{
case IDCMP_GADGETUP:
/* if a code is set in the hook after an SGH_KEY
** command, where SGA_END is set on return from
** the hook, the code will be returned in the Code
** field of the IDCMP_GADGETUP message.
*/
break;
case IDCMP_CLOSEWINDOW:
return;
break;
}
}
}
}
/*
** IsHexDigit()
**
** Return TRUE if the character is a hex digit (0-9, A-F, a-f)
*/
BOOL IsHexDigit(UBYTE test_char)
{
test_char = ToUpper(test_char);
if (((test_char >= '0') && (test_char <= '9')) ||
((test_char >= 'A') && (test_char <= 'F')))
return(TRUE);
else
return(FALSE);
}